package com.zut.domain.sevice.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.google.gson.Gson;
import com.zut.auth.infra.entity.*;
import com.zut.auth.infra.service.*;
import com.zut.common.enums.IsDeletedFlagEnum;
import com.zut.common.enums.StatusFlagEnum;
import com.zut.domain.convert.AuthUserBOConverter;
import com.zut.domain.entity.AuthUserBO;
import com.zut.domain.redis.RedisUtil;
import com.zut.domain.sevice.AuthUserDomainService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class AuthUserDomainServiceImpl implements AuthUserDomainService {


    @Resource
    private AuthUserService authUserService;

    @Resource
    private AuthUserRoleService authUserRoleService;

    @Resource
    private AuthRoleService authRoleService;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private AuthRolePermissionService authRolePermissionService;

    @Resource
    private AuthPermissionService authPermissionService;
    private String salt ="summer";

    private final String roleKey ="normal_user1";

    private static String authPermissionPrefix="auth.permission";

    private static String authRolePrefix="auth.role";

    private static final String loginKey="loginCode";

    //注册用户
    @SneakyThrows
    @Override
    @Transactional(rollbackFor = Exception.class)//开启事务,遇到异常回滚
    public Boolean register(AuthUserBO authUserBO) {
        AuthUser authUser= AuthUserBOConverter.INSTANCE.ConvertBOTo(authUserBO);

        Integer count=authUserService.queryByCondition(authUser);
        if (count>0){
            //重复登录不必再次注册
            return true;
        }
        //加盐加密，SaToken提供的类
        if(!StringUtils.isEmpty(authUserBO.getPassword())){
            String password = SaSecureUtil.md5BySalt(authUser.getPassword(), salt);
            authUser.setPassword(password);
        }
        authUser.setIsDelete(IsDeletedFlagEnum.UN_DELETED.getCode());
        authUser.setStatus(StatusFlagEnum.ENABLE.getCode());
        authUserService.insert(authUser);


        //建立初步的角色关联
        AuthRole authRole =new AuthRole();
        authRole.setRoleKey(roleKey);
        AuthRole authRoleResult = authRoleService.queryByCondition(authRole);

        AuthUserRole authUserRole =new AuthUserRole();
        authUserRole.setIsDelete(IsDeletedFlagEnum.UN_DELETED.getCode());
        authUserRole.setRoleId(authRoleResult.getId());
        authUserRole.setUserId(authUser.getId());
        int insert = authUserRoleService.insert(authUserRole);

        //信息同步到redis中
        String RoleKey = redisUtil.buildKey(authRolePrefix, authUser.getUserName());
        List<AuthRole> authRoleList=new ArrayList<>();
        authRoleList.add(authRole);
        redisUtil.set(RoleKey,new Gson().toJson(authRoleList));
        //通过角色id查询权限
        AuthRolePermission authRolePermission =new AuthRolePermission();
        authRolePermission.setRoleId(authRoleResult.getId());
        List<AuthRolePermission> authRolePermissionList =authRolePermissionService.queryByCondition(authRolePermission);
        //将查到的权限角色对象集合转换为权限id集合
        List<Integer> permissionIdList = authRolePermissionList.stream().map(AuthRolePermission::getPermissionId).collect(Collectors.toList());

        List<AuthPermission> permissionList=authPermissionService.queryByCondition(permissionIdList);
        String permissionKey =redisUtil.buildKey(authPermissionPrefix,authUser.getUserName());
        redisUtil.set(permissionKey,new Gson().toJson(permissionList));



        return insert>0;
    }

    //更改用户信息
    @Override
    public Boolean update(AuthUserBO authUserBO) {
        AuthUser authUser = AuthUserBOConverter.INSTANCE.ConvertBOTo(authUserBO);
        Boolean update = authUserService.update(authUser);
        return update;
    }

    @Override
    public Boolean delete(AuthUserBO authUserBO) {
        AuthUser authUser = AuthUserBOConverter.INSTANCE.ConvertBOTo(authUserBO);
        authUser.setIsDelete(IsDeletedFlagEnum.DELETED.getCode());
        Boolean update = authUserService.update(authUser);
        return update;
    }

    @Override
    public SaTokenInfo doLogin(String validCode) {
        String login = redisUtil.buildKey(loginKey, validCode);
        //得到缓存中的用户名（微信名）
        String username = redisUtil.get(login);
        if (!StringUtils.isBlank(username)){

            AuthUserBO authUserBO=new AuthUserBO();
            //微信名即为用户名
            authUserBO.setUserName(username);
            this.register(authUserBO);
            StpUtil.login(username);
            SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
            return tokenInfo;
        }
        return null;
    }

    @Override
    public AuthUserBO getUserInfo(AuthUserBO authUserBO) {
        AuthUser authUser1 = AuthUserBOConverter.INSTANCE.ConvertBOTo(authUserBO);
        AuthUser authUser=authUserService.getUserInfo(authUser1);
        return AuthUserBOConverter.INSTANCE.ConvertToBO(authUser);

    }


}
